package com.sihan.swvp.sync.task;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.sihan.swvp.common.CommonUtil;

/**
 * HTTP数据同步器
 * @author jch
 *
 */
@Component
public class HttpSynchronizer extends TaskSynchronizer{
	
	//http url
	public String url;
	//提交方式
	public String method = "post";
	//数据节点
	public String root = "root";
	//开始时间参数字段
	public String starttimekey = "starttime";
	//结束时间参数字段
	public String endtimekey = "endtime";
	//时间参数格式
	public String datepattern = "yyyy-MM-dd HH:mm:ss";
	//目标数据表
	public String datatable;
	//目标数据表关键字
	public String datakey;
	
	//字段类型映射
	public Map<String,Fmp> mapping = new HashMap<String,Fmp>();

	@Override
	public void sync() throws Exception {
		Date starttime = getLastDate();
		Date endtime = new Date();
		
		sync(starttime,endtime);
	}

	@SuppressWarnings("rawtypes")
	@Override
	public void sync(Date starttime, Date endtime) throws Exception {
		Date syncDate = new Date();
		// TODO Auto-generated method stub
		params.put(starttimekey, CommonUtil.date2string(starttime, datepattern));
		params.put(endtimekey, CommonUtil.date2string(endtime, datepattern));
		
		//封装请求参数  
        List<NameValuePair> urlparams = new ArrayList<NameValuePair>();  
        Set<String> keys = params.keySet();
        for (String key : keys) {
        	urlparams.add(new BasicNameValuePair(key, params.get(key)));  
		}
		
		CloseableHttpClient client = null;
		try {
			client = HttpClients.createDefault();
			try {
				List<Map> datas = getRaw(client,urlparams);
	        	saveData(datas);
	        	
	        	syncService.updateSyncTime(jobid, syncDate,"成功",true);
			} catch (Exception e) {
				// TODO: handle exception
				e.printStackTrace();
				syncService.updateSyncTime(jobid, syncDate,"失败",false);
				
				 throw new Exception(e);
			}
			
		} catch (Exception e) {
			// TODO: handle exception
			throw e;
		}
		finally{
			CommonUtil.close(client);
		}
	}
	
	
	/**
	 * 同步原始数据
	 * @param client 链接
	 * @param urlparams 参数
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public List<Map> getRaw(CloseableHttpClient client,List<NameValuePair> urlparams) throws Exception{
		CloseableHttpResponse httpResponse = null;
        try{
            if(method.toLowerCase().equals("get")){
            	//发送get请求
            	String sparams = EntityUtils.toString(new UrlEncodedFormEntity(urlparams, Consts.UTF_8));  
            	HttpGet get = new HttpGet(url+"?"+sparams);
            	httpResponse = client.execute(get);
            }
            else{
            	//发送post请求
            	HttpPost post = new HttpPost(url);
        		//url格式编码
                UrlEncodedFormEntity uefEntity = new UrlEncodedFormEntity(urlparams,"UTF-8");
                post.setEntity(uefEntity);
            	//发送get请求
                httpResponse = client.execute(post);
            }
            
            //response实体
            HttpEntity entity = httpResponse.getEntity();
            if (null != entity){
            	String rst = EntityUtils.toString(entity, "UTF-8");
            	
            	if(root.toLowerCase().equals("root")){
            		List<Map> jsa = JSON.parseArray(rst,Map.class);
            		
            		return jsa;
            	}
            	else{
            		if(root.contains(".")){
            			JSONObject dataroot = JSON.parseObject(rst);
            			String[] paths = root.split("\\.");
            			for (int i = 0; i < paths.length-1; i++) {
            				String path = paths[i];
            				dataroot = dataroot.getJSONObject(path);
						}
            			
            			return (List<Map>)dataroot.get(root);
            		}
            		else{
            			return (List<Map>)JSON.parseObject(rst).get(root);
            		}
            	}
            }
        } catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			
			throw e;
		}
        finally{
        	CommonUtil.close(httpResponse);
        }
		
		return null;
	}
	
	/**
	 * 保存数据
	 * @param raws 原始数据
	 */
	@SuppressWarnings("rawtypes")
	public void saveData(List<Map> raws) {
		for (Map<String, Object> raw : raws) {
			Map<String, Object> data = transfer(raw);
			Map<String,Object> params = new HashMap<String,Object>();
			params.put(datakey, data.get(datakey));
			List<Map<String,Object>> datas = syncService.exeSelection(datatable, datafields, params);
			if(datas.isEmpty()){
				Object[] values = new Object[datafields.length];
				for (int i = 0; i < datafields.length; i++) {
					values[i] = data.get(datafields[i]);
				}
				syncService.exeInsert(datatable, datafields, values, params);
			}
			else{
				syncService.exeUpdate(datatable, data, params);
			}
		}
		
	}
	
	/**
	 * 数据映射
	 * @param raw
	 * @return
	 */
	public Map<String,Object> transfer(Map<String,Object> raw){
		Map<String,Object> data = new HashMap<String,Object>();
		for (int i = 0; i < rawfields.length; i++) {
			if(mapping.containsKey(datafields[i])){
				Fmp fm = mapping.get(datafields[i]);
				data.put(datafields[i], fm.trans(raw.get(rawfields[i])));
			}
			else{
				data.put(datafields[i], raw.get(rawfields[i]));
			}
		}
		
		return data;
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public String getMethod() {
		return method;
	}

	public void setMethod(String method) {
		this.method = method;
	}

	public String getRoot() {
		return root;
	}

	public void setRoot(String root) {
		this.root = root;
	}

	public String getStarttimekey() {
		return starttimekey;
	}

	public void setStarttimekey(String starttimekey) {
		this.starttimekey = starttimekey;
	}

	public String getEndtimekey() {
		return endtimekey;
	}

	public void setEndtimekey(String endtimekey) {
		this.endtimekey = endtimekey;
	}

	public String getDatepattern() {
		return datepattern;
	}

	public void setDatepattern(String datepattern) {
		this.datepattern = datepattern;
	}

	public String getDatakey() {
		return datakey;
	}

	public void setDatakey(String datakey) {
		this.datakey = datakey;
	}

	public String getDatatable() {
		return datatable;
	}

	public void setDatatable(String datatable) {
		this.datatable = datatable;
	}

	public Map<String, Fmp> getMapping() {
		return mapping;
	}

	public void setMapping(Map<String, Fmp> mapping) {
		this.mapping = mapping;
	}
	
	
}
